home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / actionrp / nhplusx.bin / nhplusx / nhplusX / X11 / winmisc.c < prev    next >
C/C++ Source or Header  |  1995-09-10  |  13KB  |  511 lines

  1. /*    SCCS Id: @(#)winmisc.c    3.1    93/02/04    */
  2. /* Copyright (c) Dean Luick, 1992                  */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. /*
  6.  * Misc. popup windows: player selection and extended commands.
  7.  * 
  8.  *     + Global functions: player_selection() and get_ext_cmd().
  9.  */
  10.  
  11. #ifndef SYSV
  12. #define PRESERVE_NO_SYSV    /* X11 include files may define SYSV */
  13. #endif
  14.  
  15. #include <X11/Intrinsic.h>
  16. #include <X11/StringDefs.h>
  17. #include <X11/Shell.h>
  18. #include <X11/Xaw/Command.h>
  19. #include <X11/Xaw/Form.h>
  20. #include <X11/Xaw/Label.h>
  21. #include <X11/Xaw/Cardinals.h>
  22. #include <X11/Xos.h>    /* for index() */
  23. #include <X11/Xatom.h>
  24.  
  25. #ifdef PRESERVE_NO_SYSV
  26. # ifdef SYSV
  27. #  undef SYSV
  28. # endif
  29. # undef PRESERVE_NO_SYSV
  30. #endif
  31.  
  32. #include "hack.h"
  33. #include "func_tab.h"
  34. #include "winX.h"
  35.  
  36. extern const char *roles[];    /* from u_init.c */
  37.  
  38. static Widget extended_command_popup;
  39. static Widget extended_command_form;
  40. static int extended_command_selected;    /* index of the selected command; */
  41. static int ps_selected;            /* index of selected role */
  42. #define PS_RANDOM (-50)
  43. #define PS_QUIT   (-75)
  44.  
  45. static const char extended_command_translations[] =
  46.     "#override\n\
  47.      <Key>: ec_key()";
  48.  
  49. static const char player_select_translations[] =
  50.     "#override\n\
  51.      <Key>: ps_key()";
  52.  
  53.  
  54. static Widget FDECL(make_menu, (const char *,const char *,String,
  55.                 const char *,XtCallbackProc,
  56.                 const char *,XtCallbackProc,
  57.                 int,char **,XtCallbackProc,Widget *));
  58.  
  59.  
  60. /* Player Selection -------------------------------------------------------- */
  61. /* ARGSUSED */
  62. static void
  63. ps_quit(w, client_data, call_data)
  64.     Widget w;
  65.     XtPointer client_data, call_data;
  66. {
  67.     ps_selected = PS_QUIT;
  68.     exit_x_event = TRUE;        /* leave event loop */
  69. }
  70.  
  71. /* ARGSUSED */
  72. static void
  73. ps_random(w, client_data, call_data)
  74.     Widget w;
  75.     XtPointer client_data, call_data;
  76. {
  77.     ps_selected = PS_RANDOM;
  78.     exit_x_event = TRUE;        /* leave event loop */
  79. }
  80.  
  81. /* ARGSUSED */
  82. static void
  83. ps_select(w, client_data, call_data)
  84.     Widget w;
  85.     XtPointer client_data, call_data;
  86. {
  87.     ps_selected = (int) client_data;
  88.     exit_x_event = TRUE;        /* leave event loop */
  89. }
  90.  
  91. /* ARGSUSED */
  92. void
  93. ps_key(w, event, params, num_params)
  94.     Widget w;
  95.     XEvent *event;
  96.     String *params;
  97.     Cardinal *num_params;
  98. {
  99.     char ch, *mark;
  100.  
  101.     ch = key_event_to_char((XKeyEvent *) event);
  102.     if (ch == '\0') {    /* don't accept nul char/modifier event */
  103.     /* don't beep */
  104.     return;
  105.     }
  106.     mark = index(pl_classes, highc(ch));
  107.     if (!mark) {
  108.     X11_nhbell();        /* no such class */
  109.     return;
  110.     }
  111.     ps_selected = mark - pl_classes;
  112.     exit_x_event = TRUE;
  113. }
  114.  
  115.  
  116. /* Global functions ========================================================= */
  117. void
  118. X11_player_selection()
  119. {
  120.     char buf[QBUFSZ];
  121.     char pc;
  122.     int num_roles;
  123.     Widget popup, player_form;
  124.  
  125.     if ((pc = highc(pl_character[0])) != 0) {
  126.     if (index(pl_classes, pc)) goto got_suffix;
  127.     pl_character[0] = pc = 0;
  128.     }
  129.  
  130.     for (num_roles = 0; roles[num_roles]; num_roles++)
  131.     ;    /* do nothing */
  132.  
  133.     popup = make_menu("player_selection", "Choose a Role",
  134.         player_select_translations,
  135.         "quit", ps_quit,
  136.         "random", ps_random,
  137.         num_roles, roles, ps_select, &player_form);
  138.  
  139.     ps_selected = 0;
  140.     positionpopup(popup, FALSE);
  141.     nh_XtPopup(popup, (int)XtGrabExclusive, player_form);
  142.  
  143.     /* The callbacks will enable the event loop exit. */
  144.     (void) x_event(EXIT_ON_EXIT);
  145.  
  146.     nh_XtPopdown(popup);
  147.     XtDestroyWidget(popup);
  148.  
  149.     if (ps_selected == PS_QUIT) {
  150.     clearlocks();
  151.     X11_exit_nhwindows(NULL);
  152.     terminate(0);
  153.     }
  154.  
  155.     if (ps_selected == PS_RANDOM) {
  156.     winid tmpwin;
  157.  
  158.     ps_selected = rn2(strlen(pl_classes));
  159.     pc = pl_classes[ps_selected];
  160.     Sprintf(buf, "This game you will be %s.", an(roles[ps_selected]));
  161.  
  162.     tmpwin = X11_create_nhwindow(NHW_TEXT);
  163.     X11_putstr(tmpwin, 0, "");
  164.     X11_putstr(tmpwin, 0, buf);
  165.     X11_putstr(tmpwin, 0, "");
  166.     X11_display_nhwindow(tmpwin, TRUE);
  167.     X11_destroy_nhwindow(tmpwin);
  168.  
  169.     } else if (ps_selected < 0 || ps_selected >= num_roles) {
  170.     panic("player_selection: bad select value %d\n", ps_selected);
  171.     } else {
  172.     pc = pl_classes[ps_selected];
  173.     }
  174.  
  175. got_suffix:
  176.     pl_character[0] = pc;
  177. }
  178.  
  179.  
  180. void
  181. X11_get_ext_cmd(input)
  182.     char *input;
  183. {
  184.     extended_command_selected = -1;        /* reset selected value */
  185.  
  186.     positionpopup(extended_command_popup, FALSE); /* center on cursor */
  187.     nh_XtPopup(extended_command_popup, (int)XtGrabExclusive,
  188.                     extended_command_form);
  189.  
  190.     /* The callbacks will enable the event loop exit. */
  191.     (void) x_event(EXIT_ON_EXIT);
  192.  
  193.     if (extended_command_selected < 0)
  194.     *input = '\0';
  195.     else
  196.     Strcpy(input, extcmdlist[extended_command_selected].ef_txt);
  197. }
  198.  
  199. /* End global functions ===================================================== */
  200.  
  201. /* Extended Command -------------------------------------------------------- */
  202. /* ARGSUSED */
  203. static void
  204. extend_select(w, client_data, call_data)
  205.     Widget w;
  206.     XtPointer client_data, call_data;
  207. {
  208.     extended_command_selected = (int) client_data;
  209.     nh_XtPopdown(extended_command_popup);
  210.     exit_x_event = TRUE;        /* leave event loop */
  211. }
  212.  
  213. /* ARGSUSED */
  214. static void
  215. extend_dismiss(w, client_data, call_data)
  216.     Widget w;
  217.     XtPointer client_data, call_data;
  218. {
  219.     extended_command_selected = -1;    /* dismiss */
  220.     nh_XtPopdown(extended_command_popup);
  221.     exit_x_event = TRUE;        /* leave event loop */
  222. }
  223.  
  224. /* ARGSUSED */
  225. static void
  226. extend_help(w, client_data, call_data)
  227.     Widget w;
  228.     XtPointer client_data, call_data;
  229. {
  230.     /* We might need to make it known that we already have one listed. */
  231.     (void) doextlist();
  232. }
  233.  
  234. /* ARGSUSED */
  235. void
  236. ec_delete(w, event, params, num_params)
  237.     Widget w;
  238.     XEvent *event;
  239.     String *params;
  240.     Cardinal *num_params;
  241. {
  242.     extended_command_selected = -1;    /* dismiss */
  243.     nh_XtPopdown(extended_command_popup);
  244.     exit_x_event = TRUE;        /* leave event loop */
  245. }
  246.  
  247. /* ARGSUSED */
  248. void
  249. ec_key(w, event, params, num_params)
  250.     Widget w;
  251.     XEvent *event;
  252.     String *params;
  253.     Cardinal *num_params;
  254. {
  255.     char ch;
  256.     int i, mark;
  257.  
  258.     ch = key_event_to_char((XKeyEvent *) event);
  259.  
  260.     if (ch == '\0') {    /* don't accept nul char/modifier event */
  261.     /* don't beep */
  262.     return;
  263.     }
  264.     if (index(quitchars, ch)) {
  265.     extended_command_selected = -1;    /* dismiss */
  266.     goto ec_key_done;
  267.     }
  268.  
  269.     /*
  270.      * Note: this depends on the fact that the help option "?" is known
  271.      * to be last and not counted.
  272.      */
  273.     for (mark = -1, i = 0; extcmdlist[i].ef_txt; i++) {
  274.     if (extcmdlist[i].ef_txt[0] == '?') continue;
  275.  
  276.     if (ch == extcmdlist[i].ef_txt[0]) {
  277.         if (mark != -1) {
  278.         X11_nhbell(); /* another command with the same first letter */
  279.         return;
  280.         }
  281.         mark = i;
  282.     }
  283.     }
  284.     if (mark == -1) {
  285.     X11_nhbell();
  286.     return;
  287.     }
  288.  
  289.     /*
  290.      * It would be nice if we could set the selected command before
  291.      * we pop the window down....  Maybe when I figure out how to do
  292.      * it.
  293.      */
  294.     extended_command_selected = mark;
  295. ec_key_done:
  296.     nh_XtPopdown(extended_command_popup);
  297.     exit_x_event = TRUE;        /* leave event loop */
  298. }
  299.  
  300. /*
  301.  * Use our own home-brewed version menu because simpleMenu is designed to
  302.  * be used from a menubox.
  303.  */
  304. void
  305. init_extended_commands_popup()
  306. {
  307.     int i, num_commands;
  308.     const char **command_list;
  309.  
  310.     /* count commands */
  311.     for (num_commands = 0; extcmdlist[num_commands].ef_txt; num_commands++)
  312.     ;    /* do nothing */
  313.  
  314.     /* If the last entry is "help", don't use it. */
  315.     if (strcmp(extcmdlist[num_commands-1].ef_txt, "?") == 0)
  316.     --num_commands;
  317.  
  318.     command_list = (const char **) alloc(num_commands * sizeof(char *));
  319.  
  320.     for (i = 0; i < num_commands; i++)
  321.     command_list[i] = extcmdlist[i].ef_txt;
  322.  
  323.     extended_command_popup = make_menu("extended_commands",
  324.                 "Extended Commands",
  325.                 extended_command_translations,
  326.                 "dismiss", extend_dismiss,
  327.                 "help", extend_help,
  328.                 num_commands, command_list, extend_select,
  329.                 &extended_command_form);
  330.  
  331.     free((char *)command_list);
  332. }
  333.  
  334. /* ------------------------------------------------------------------------- */
  335.  
  336. /*
  337.  * Create a popup widget of the following form:
  338.  * 
  339.  *              popup_label
  340.  *        ----------- ------------
  341.  *         |left_name| |right_name|
  342.  *        ----------- ------------
  343.  *        ------------------------
  344.  *        |    name1           |
  345.  *        ------------------------
  346.  *        ------------------------
  347.  *        |    name2           |
  348.  *        ------------------------
  349.  *              .
  350.  *              .
  351.  *        ------------------------
  352.  *        |    nameN           |
  353.  *        ------------------------
  354.  */
  355. static Widget
  356. make_menu(popup_name, popup_label, popup_translations,
  357.         left_name, left_callback,
  358.         right_name, right_callback,
  359.         num_names, widget_names, name_callback, formp)
  360.     const char       *popup_name;
  361.     const char       *popup_label;
  362.     String       popup_translations;
  363.     const char       *left_name;
  364.     XtCallbackProc left_callback;
  365.     const char       *right_name;
  366.     XtCallbackProc right_callback;
  367.     int           num_names;
  368.     char       **widget_names;
  369.     XtCallbackProc name_callback;
  370.     Widget       *formp;    /* return */
  371. {
  372.     Widget popup, form, label, above, left, right;
  373.     Widget *commands, *curr;
  374.     int i;
  375.     Arg args[8];
  376.     Cardinal num_args;
  377.     Dimension width, max_width;
  378.     int distance, skip;
  379.  
  380.  
  381.     commands = (Widget *) alloc(num_names * sizeof(Widget));
  382.  
  383.  
  384.     num_args = 0;
  385.     XtSetArg(args[num_args], XtNallowShellResize, True);    num_args++;
  386.  
  387.     popup = XtCreatePopupShell(popup_name,
  388.                 transientShellWidgetClass,
  389.                 toplevel, args, num_args);
  390.     XtOverrideTranslations(popup,
  391.     XtParseTranslationTable("<Message>WM_PROTOCOLS: ec_delete()"));
  392.  
  393.     num_args = 0;
  394.     XtSetArg(args[num_args], XtNtranslations,
  395.         XtParseTranslationTable(popup_translations));    num_args++;
  396.     *formp = form = XtCreateManagedWidget("menuform",
  397.                 formWidgetClass,
  398.                 popup,
  399.                 args, num_args);
  400.  
  401.     /* Get the default distance between objects in the form widget. */
  402.     num_args = 0;
  403.     XtSetArg(args[num_args], XtNdefaultDistance, &distance);    num_args++;
  404.     XtGetValues(form, args, num_args);
  405.  
  406.     /*
  407.      * Create the label.
  408.      */
  409.     num_args = 0;
  410.     XtSetArg(args[num_args], XtNborderWidth, 0);    num_args++;
  411.     label = XtCreateManagedWidget(popup_label,
  412.                 labelWidgetClass,
  413.                 form,
  414.                 args, num_args);
  415.  
  416.     /*
  417.      * Create the left button.
  418.      */
  419.     num_args = 0;
  420.     XtSetArg(args[num_args], XtNfromVert, label);        num_args++;
  421. /*
  422.     XtSetArg(args[num_args], XtNshapeStyle,
  423.                 XmuShapeRoundedRectangle);    num_args++;
  424. */
  425.     left = XtCreateManagedWidget(left_name,
  426.             commandWidgetClass,
  427.             form,
  428.             args, num_args);
  429.     XtAddCallback(left, XtNcallback, left_callback, (XtPointer) 0);
  430.     skip = 3*distance;    /* triple the spacing */
  431.     if(!skip) skip = 3;
  432.  
  433.     /*
  434.      * Create right button.
  435.      */
  436.     num_args = 0;
  437.     XtSetArg(args[num_args], XtNfromHoriz, left);        num_args++;
  438.     XtSetArg(args[num_args], XtNfromVert, label);        num_args++;
  439. /*
  440.     XtSetArg(args[num_args], XtNshapeStyle,
  441.                 XmuShapeRoundedRectangle);    num_args++;
  442. */
  443.     right = XtCreateManagedWidget(right_name,
  444.             commandWidgetClass,
  445.             form,
  446.             args, num_args);
  447.     XtAddCallback(right, XtNcallback, right_callback, (XtPointer) 0);
  448.  
  449.     XtInstallAccelerators(form, left);
  450.     XtInstallAccelerators(form, right);
  451.  
  452.     /*
  453.      * Create and place the command widgets.
  454.      */
  455.     for (i = 0, above = left, curr = commands; i < num_names;
  456.                     i++, above = *curr, curr++) {
  457.     num_args = 0;
  458.     XtSetArg(args[num_args], XtNfromVert, above);    num_args++;
  459.     if (i == 0) {
  460.         /* if first, we are farther apart */
  461.         XtSetArg(args[num_args], XtNvertDistance, skip);    num_args++;
  462.     }
  463.  
  464.     *curr = XtCreateManagedWidget(widget_names[i],
  465.             commandWidgetClass,
  466.             form,
  467.             args, num_args);
  468.     XtAddCallback(*curr, XtNcallback, name_callback, (XtPointer) i);
  469.     }
  470.  
  471.     /*
  472.      * Now find the largest width.  Start with the width dismiss + help
  473.      * buttons, since they are adjacent.
  474.      */
  475.     XtSetArg(args[0], XtNwidth, &max_width);
  476.     XtGetValues(left, args, ONE);
  477.     XtSetArg(args[0], XtNwidth, &width);
  478.     XtGetValues(right, args, ONE);
  479.     max_width = max_width + width + distance;
  480.  
  481.     /* Next, the title. */
  482.     XtSetArg(args[0], XtNwidth, &width);
  483.     XtGetValues(label, args, ONE);
  484.     if (width > max_width) max_width = width;
  485.  
  486.     /* Finally, the commands. */
  487.     for (i = 0, curr = commands; i < num_names; i++, curr++) {
  488.     XtSetArg(args[0], XtNwidth, &width);
  489.     XtGetValues(*curr, args, ONE);
  490.     if (width > max_width) max_width = width;
  491.     }
  492.  
  493.     /*
  494.      * Finally, set all of the single line widgets to the largest width.
  495.      */
  496.     XtSetArg(args[0], XtNwidth, max_width);
  497.     XtSetValues(label, args, ONE);
  498.  
  499.     for (i = 0, curr = commands; i < num_names; i++, curr++) {
  500.     XtSetArg(args[0], XtNwidth, max_width);
  501.     XtSetValues(*curr, args, ONE);
  502.     }
  503.  
  504.     free((char *) commands);
  505.  
  506.     XtRealizeWidget(popup);
  507.     XSetWMProtocols(XtDisplay(popup), XtWindow(popup), &wm_delete_window, 1);
  508.  
  509.     return popup;
  510. }
  511.